package com.flxz.user.service.impl;

import com.flxz.common.core.domain.entity.SysUser;
import com.flxz.user.domain.UserExpense;
import com.flxz.user.domain.UserIncome;
import com.flxz.user.domain.vo.ChartDataVO;
import com.flxz.user.mapper.UserExpenseMapper;
import com.flxz.user.mapper.UserIncomeMapper;
import com.flxz.user.service.IUserChartService;
import com.flxz.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户图表统计Service业务层处理
 */
@Service
public class UserChartServiceImpl implements IUserChartService {

    @Autowired
    private UserIncomeMapper userIncomeMapper;

    @Autowired
    private UserExpenseMapper userExpenseMapper;

    @Autowired
    private ISysUserService sysUserService;

    @Override
    public ChartDataVO getChartData(Long userId, String timeRange, String startDate, String endDate) {
        ChartDataVO chartData = new ChartDataVO();

        // 获取时间范围
        Date[] dateRange = getDateRange(timeRange, startDate, endDate);
        Date start = dateRange[0];
        Date end = dateRange[1];

        // 获取用户信息
        SysUser user = sysUserService.selectUserById(userId);
        BigDecimal expectedExpense = user.getMonthlyExpense() != null ? BigDecimal.valueOf(user.getMonthlyExpense()) : BigDecimal.ZERO;
        BigDecimal fixedIncome = user.getMonthlyIncome() != null ? BigDecimal.valueOf(user.getMonthlyIncome()) : BigDecimal.ZERO;

        // 查询收入数据
        UserIncome incomeQuery = new UserIncome();
        incomeQuery.setUserId(userId);
        List<UserIncome> incomeList = userIncomeMapper.selectUserIncomeList(incomeQuery);
        
        // 过滤时间范围内的收入
        List<UserIncome> filteredIncomeList = incomeList.stream()
                .filter(income -> income.getIncomeTime().compareTo(start) >= 0 && income.getIncomeTime().compareTo(end) <= 0)
                .collect(Collectors.toList());

        // 查询支出数据
        UserExpense expenseQuery = new UserExpense();
        expenseQuery.setUserId(userId);
        List<UserExpense> expenseList = userExpenseMapper.selectUserExpenseList(expenseQuery);
        
        // 过滤时间范围内的支出
        List<UserExpense> filteredExpenseList = expenseList.stream()
                .filter(expense -> expense.getExpenseTime().compareTo(start) >= 0 && expense.getExpenseTime().compareTo(end) <= 0)
                .collect(Collectors.toList());

        // 计算实际支出总额
        BigDecimal actualExpense = filteredExpenseList.stream()
                .map(UserExpense::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 计算其他收入（非固定收入）
        BigDecimal otherIncome = filteredIncomeList.stream()
                .map(UserIncome::getAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 设置支出对比数据
        ChartDataVO.ExpensePieData expensePieData = new ChartDataVO.ExpensePieData();
        expensePieData.setActualExpense(actualExpense);
        expensePieData.setExpectedExpense(expectedExpense);
        chartData.setExpensePie(expensePieData);

        // 设置收入构成数据
        ChartDataVO.IncomePieData incomePieData = new ChartDataVO.IncomePieData();
        incomePieData.setFixedIncome(fixedIncome);
        incomePieData.setOtherIncome(otherIncome);
        chartData.setIncomePie(incomePieData);

        // 生成支出分类柱状图数据
        Map<Long, BigDecimal> expenseCategoryMap = new HashMap<>();
        for (UserExpense expense : filteredExpenseList) {
            Long categoryId = expense.getCategoryId();
            BigDecimal amount = expense.getAmount();
            expenseCategoryMap.merge(categoryId, amount, BigDecimal::add);
        }
        
        List<Map<String, Object>> expenseBarData = new ArrayList<>();
        for (Map.Entry<Long, BigDecimal> entry : expenseCategoryMap.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("category", getCategoryName(entry.getKey(), "expense"));
            item.put("amount", entry.getValue());
            expenseBarData.add(item);
        }
        chartData.setExpenseBar(expenseBarData);

        // 生成收入分类柱状图数据
        Map<Long, BigDecimal> incomeCategoryMap = new HashMap<>();
        for (UserIncome income : filteredIncomeList) {
            Long categoryId = income.getCategoryId();
            BigDecimal amount = income.getAmount();
            incomeCategoryMap.merge(categoryId, amount, BigDecimal::add);
        }
        
        List<Map<String, Object>> incomeBarData = new ArrayList<>();
        for (Map.Entry<Long, BigDecimal> entry : incomeCategoryMap.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("category", getCategoryName(entry.getKey(), "income"));
            item.put("amount", entry.getValue());
            incomeBarData.add(item);
        }
        chartData.setIncomeBar(incomeBarData);

        return chartData;
    }

    /**
     * 获取时间范围
     */
    private Date[] getDateRange(String timeRange, String startDate, String endDate) {
        Date start, end;
        
        if (startDate != null && endDate != null) {
            // 使用自定义日期范围
            start = java.sql.Date.valueOf(startDate);
            end = java.sql.Date.valueOf(endDate);
        } else {
            // 使用预设时间范围
            LocalDate now = LocalDate.now();
            switch (timeRange) {
                case "week":
                    start = Date.from(now.minusWeeks(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
                    end = Date.from(now.atStartOfDay(ZoneId.systemDefault()).toInstant());
                    break;
                case "year":
                    start = Date.from(now.withDayOfYear(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
                    end = Date.from(now.atStartOfDay(ZoneId.systemDefault()).toInstant());
                    break;
                case "month":
                default:
                    start = Date.from(now.withDayOfMonth(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
                    end = Date.from(now.atStartOfDay(ZoneId.systemDefault()).toInstant());
                    break;
            }
        }
        
        return new Date[]{start, end};
    }

    /**
     * 获取分类名称（这里简化处理，实际应该从数据库或缓存中获取）
     */
    private String getCategoryName(Long categoryId, String type) {
        // 这里应该从数据库查询分类名称，暂时返回默认值
        if ("expense".equals(type)) {
            switch (categoryId.intValue()) {
                case 1: return "餐饮";
                case 2: return "交通";
                case 3: return "购物";
                case 4: return "娱乐";
                case 5: return "居住";
                case 6: return "医疗";
                case 7: return "教育";
                default: return "其他支出";
            }
        } else {
            switch (categoryId.intValue()) {
                case 1: return "工资";
                case 2: return "奖金";
                case 3: return "投资收益";
                case 4: return "意外之财";
                default: return "其他收入";
            }
        }
    }
}
